package com.nonagon.melladesk.handler;

import com.nonagon.melladesk.entity.PetEntity;
import com.nonagon.melladesk.entity.RoleEntity;
import com.nonagon.melladesk.entity.UserEntity;
import com.nonagon.melladesk.repository.*;
import com.nonagon.melladesk.service.RedisService;
import com.nonagon.melladesk.utils.JwtUtil;
import com.nonagon.melladesk.utils.R;
import com.nonagon.melladesk.utils.RRException;
import com.nonagon.melladesk.utils.StatusCode;
import com.nonagon.melladesk.vo.UserDetail;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static org.springframework.web.reactive.function.server.ServerResponse.notFound;

/**
 * @author flitsneak
 * @ClassName 用户接口
 * @date 2021/4/6 10:31
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class UserHandler {

    private final UserRepository userRepository;

    private final UserRoleRepository userRoleRepository;

    private final RoleRepository roleRepository;

    private final UserIdentityRepository userIdentityRepository;

    private final IdentityRepository identityRepository;

    private final PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();

    private final JwtUtil jwtUtil;

    private final RedisService redisService;

    /**
     * 登录接口，springsecurityreactive必须接口
     * @param serverRequest
     * @return
     */
    public Mono<ServerResponse> login(ServerRequest serverRequest){
        Mono<UserDetail> userDetailMono = serverRequest.bodyToMono(UserDetail.class);
        UserDetail userDetail = new UserDetail();
        Set<RoleEntity> roles = new HashSet<>();
        log.info("访问 login");
        //查找用户信息，包括账户密码以及权限
        return userDetailMono.flatMap(u -> userRepository.findAllByEmail(u.getEmail()))
                .flatMap(p -> {
                    userIdentityRepository.findByIdentityTypeIdAndUserId(1, p.getUserId())
                            .subscribe(q -> {
                                identityRepository.findById(q.getIdentityId())
                                        .subscribe(h -> userDetail.setHash(h.getHash()));
                            });
                    userRoleRepository.findAllByUserId(p.getUserId()).subscribe(q -> roleRepository.findById(q.getRoleId())
                            .subscribe(r -> roles.add(r)));
                    userDetail.setRoles(roles);
                    return Mono.just(userDetail);
                }).flatMap(i->{
            List<String> list = i.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
            String token = jwtUtil.generateToken(userDetail);
            redisService.saveToken(token);
            return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).bodyValue(new R(true,StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMsg(),token));
        }).switchIfEmpty(notFound().build());

}}
